package com.projeto.infra.business;

import com.projeto.business.controller.EventController;
import com.projeto.business.controller.UserController;
import com.projeto.persistence.Event;
import com.projeto.persistence.User;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.SessionContext;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

public abstract class GenericBean<T extends GenericEntity> {
		
        @Resource
        protected SessionContext ctx;    
        
        @EJB
        EventController eventBean;
            
	@PersistenceContext(unitName = "final")
	protected EntityManager em;
	
	public EntityManager getEntityManager() {
            return em;
	}
        
        @TransactionAttribute(TransactionAttributeType.REQUIRED)
        public void save(T t)
        {
            if(validate(t))
            {
                String userLogin = ctx.getCallerPrincipal().getName();
                Event e1 = new Event();
                if (t.getCreateDt() != null)
                {
                    T entity = (T)em.find(t.getClass(), t.getId());
                    e1.setBefore(entity.toString());
                    e1.setEvent(Event.EVENT.UPDATE);
                }
                else
                {
                    User user = em.find(User.class, userLogin);    
                    t.setCreateDt(new Date());
                    t.setCreatedBy(user);
                    e1.setEvent(Event.EVENT.INSERT);
                }
                e1.setAfter(t.toString());
                e1.setCreateDt(new Date());
                
                e1.setId(UUID.randomUUID().toString());                
                
                e1.setCreatedBy(userLogin);
                eventBean.save(e1);
                
                em.persist(t);
            }
        }
        
        @TransactionAttribute(TransactionAttributeType.REQUIRED)
        public void remove(T t)
        {
            if(validate(t))
            {
                Event e1 = new Event();
                T entity = (T)em.find(t.getClass(), t.getId());
                e1.setBefore(entity.toString());
                e1.setEvent(Event.EVENT.DELETE);
                e1.setAfter(t.toString());
                e1.setCreateDt(new Date());
                
                e1.setId(UUID.randomUUID().toString());
                e1.setCreatedBy(ctx.getCallerPrincipal().getName());
                eventBean.save(e1);
                
                em.remove(t);
            }
        }
        
        protected abstract boolean validate(T e);
        protected abstract List<T> findAll();
}
